﻿namespace fastdb.Db.storage;

/// <summary>
///     存储控制器
/// </summary>
public class StorageController
{
    private readonly string _storagePath;
    private FileStream _storageStream;


    public StorageController(string folder)
    {
        _storagePath = folder;
    }

    public bool CreateDbStorage(string dbName, string password = "")
    {
        var dbPath = Path.Combine(_storagePath, dbName);
        if (File.Exists(dbPath)) File.Delete(dbPath);

        OpenDbStorage(dbName, password);

        _storageStream.Write(new DbHeader().ContentBytes);
        _storageStream.Flush(true);

        return true;
    }

    public bool OpenDbStorage(string dbName, string password = "")
    {
        var dbPath = Path.Combine(_storagePath, dbName);
        _storageStream = File.Create(dbPath, 1024 * 1024);

        return true;
    }


    public bool CloseDbStorage()
    {
        _storageStream.Flush(true);
        _storageStream.Close();
        _storageStream.Dispose();

        return true;
    }


    public bool SaveTableData(Table table)
    {
        var rowItems = table.Rows;

        var pages = new List<Page>();
        var pageNo = 0;
        var itemCountPerPage = (4096 - 96) / table.RowSize;

        for (var i = 0; i < rowItems.Count; i++)
        {
            var row = rowItems[i];

            if (i % itemCountPerPage == 0)
            {
                pageNo++;
                var p = new Page
                {
                    PageNo = pageNo,
                    ContentBytes = row.GenerateDataBytes(table.CloumnNames.Values.ToList())
                };
                pages.Add(p);
            }
        }


        SavePages(pages);

        return true;
    }


    public void SavePages(List<Page> pages)
    {
        //可能系统缓存是60M
        //大量数据写后，一般是2500页每秒。每秒4KB
        for (var i = 0; i < pages.Count; i++)
        {
            _storageStream.Seek((pages[i].PageNo - 1) * 4096, SeekOrigin.Begin);
            _storageStream.Write(pages[i].GenerateBytes());

            _storageStream.Flush(true);
        }
    }
}